package com.zoo.boot.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.zoo.boot.bean.JwtUser;
import com.zoo.boot.dao.MenuDao;
import com.zoo.boot.dto.MenuDto;
import com.zoo.boot.dto.MenuIndexDto;
import com.zoo.boot.mapper.LMenuMapper;
import com.zoo.boot.model.LMenu;
import com.zoo.boot.model.LMenuExample;
import com.zoo.boot.service.MenuService;
import com.zoo.boot.service.RedisService;
import com.zoo.boot.utils.TreeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 菜单管理实现 Service
 *
 * @Author: WangB
 * @Date: 2021/6/24
 */
@Service
public class MenuServiceImpl implements MenuService {
    @Resource
    private LMenuMapper menuMapper;

    @Resource
    private MenuDao menuDao;

    @Autowired
    private RedisService redisService;


    /**
     * 根据登录的用户信息获取菜单
     *
     * @return
     */
    @Override
    public List<MenuIndexDto> menus() {
        // 1、从security中获取 JwtUser
        // 2、从JwtUser中获取菜单
//        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        SecurityContext context = SecurityContextHolder.getContext();
        Authentication token = context.getAuthentication();
//        List<LMenu> lMenus = new ArrayList<>();
        List<LMenu> o = new ArrayList<>();

        if (ObjectUtil.isNotEmpty(token)) {
            Object principal = token.getPrincipal();
            if (ObjectUtil.isNotEmpty(principal) && principal instanceof UserDetails) {
                JwtUser jwtUser = (JwtUser) principal;
//                lMenus = jwtUser.getLMenus();
                o= (List<LMenu>) redisService.get("repast:menu:"+ jwtUser.getUser().getUserId());
            }
        }
        return loadTreeMenus(o);
    }


    /**
     * 获取菜单列表
     *
     * @return
     */
    @Override
    public List<MenuIndexDto> selectMenuList() {
        return menuDao.selectMenuList();
    }


    /**
     * 根据角色获取对应菜单
     *
     * @param roleId
     * @return
     */
    @Override
    public List<LMenu> getMenuByRoleId(Integer roleId) {
        List<LMenu> lMenus = menuDao.selectMenuByRoleId(roleId);
        return lMenus;
    }


    /**
     * 构建dtree
     *
     * @return
     */
    @Override
    public List<MenuDto> buildMenuAll() {
        return menuDao.buildMenuAll();
    }


    @Override
    public List<MenuDto> buildMenuAllByRoleId(Integer roleId) {

        //获取所有的菜单选项
        List<MenuDto> listByRoleId = menuDao.listByRoleId(roleId);

        //根据当前的角色来获取菜单
        List<MenuDto> permissionDtos = menuDao.buildMenuAll();

        List<MenuDto> tree = TreeUtils.menutree(listByRoleId, permissionDtos);
        return tree;
    }


    /**
     * 添加菜单信息
     *
     * @param info
     * @return
     */
    @Override
    public boolean insertMenu(MenuIndexDto info) {
        info.setCreateTime(new Date());
        info.setUpdateTime(new Date());
        return menuDao.insertMenu(info);
    }


    /**
     * 根据菜单id获取菜单信息
     *
     * @param id
     * @return
     */
    @Override
    public MenuIndexDto selectMenuById(Integer id) {
        MenuIndexDto menuIndexDto = menuDao.selectMenuById(id);
        return menuIndexDto;
    }

    /**
     * 根据id修改菜单
     *
     * @param info
     * @return
     */
    @Override
    public boolean update(MenuIndexDto info) {
        info.setUpdateTime(new Date());
        return menuDao.updateMenu(info);
    }


    /**
     * 根据id删除菜单及子菜单
     *
     * @param id
     * @return
     */
    @Transactional
    @Override
    public boolean delete(Integer id) {
        int i = menuMapper.deleteByPrimaryKey(id);
        LMenuExample lMenuExample = new LMenuExample();
        lMenuExample.createCriteria().andParentIdEqualTo(id);
        int i1 = menuMapper.deleteByExample(lMenuExample);
        return i > 0;
    }

    /**
     * 加工左边树菜单
     *
     * @param lMenus
     * @return
     */
    public List<MenuIndexDto> loadTreeMenus(List<LMenu> lMenus) {
        List<MenuIndexDto> collect = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(lMenus)) {
            collect = lMenus.stream()
                    .map(TreeUtils::convertMenuIndexDto)
                    .collect(Collectors.toList());
        }
        if (ObjectUtil.isNotEmpty(collect)) {
            return TreeUtils.parseMenu(collect);
        }
        return collect;
    }
}
